package mylab.starters.mongodb;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;

import java.io.Serializable;
import java.util.List;

/**
 * @author :  sylar
 * @FileName :
 * @CreateDate :  2017/11/08
 */
public class BaseMongoRepositoryImpl<E, K extends Serializable> extends SimpleMongoRepository<E, K> implements
        BaseMongoRepository<E, K> {
    protected final MongoOperations mongoTemplate;

    protected final MongoEntityInformation<E, K> entityInformation;

    public BaseMongoRepositoryImpl(MongoEntityInformation<E, K> metadata, MongoOperations mongoOperations) {
        super(metadata, mongoOperations);

        this.mongoTemplate = mongoOperations;
        this.entityInformation = metadata;
    }

    protected Class<E> getEntityClass() {
        return entityInformation.getJavaType();
    }


    @Override
    public Page<E> find(Criteria criteria) {
        return find(new Query(criteria));
    }

    @Override
    public Page<E> find(Criteria criteria, Pageable pageable) {
        return find(new Query(criteria), pageable);
    }

    @Override
    public Page<E> find(Query query) {
        return find(query, PageRequest.of(0, Integer.MAX_VALUE));
    }

    @Override
    public Page<E> find(Query query, Pageable pageable) {
        long total = mongoTemplate.count(query, getEntityClass());
        List<E> list = mongoTemplate.find(query.with(pageable), getEntityClass());

        return new PageImpl<>(list, pageable, total);
    }

    @Override
    public E findOne(Criteria criteria) {
        return findOne(new Query(criteria));
    }

    @Override
    public E findOne(Query query) {
        query = query.limit(1);
        List<E> list = mongoTemplate.find(query, getEntityClass());
        if (list.size() > 0) {
            return list.get(0);
        } else {
            return null;
        }
    }
}